#ifndef __CASE_TPL_STORE_H__
#define __CASE_TPL_STORE_H__

#include "common_types.h"
#include "basic/tpl_store.h"

class Test_tpl_store : public testing::Test {
protected:
  tpl_Store<int, AA> store;
  virtual void SetUp(){};
  virtual void TearDown(){};
};

TEST_F(Test_tpl_store, Set__Set_d__GetSize) {
  ASSERT_EQ(store.GetSize(), 0);
  bool b{false};
  AA* pAA = new AA(1, 1.1f);
  b = store.Set(1, pAA);
  ASSERT_EQ(b, true);
  ASSERT_EQ(store.GetSize(), 1);
  b = store.Set(1, pAA);
  ASSERT_EQ(b, false);
  ASSERT_EQ(store.GetSize(), 1);
  b = store.Set(2, pAA);
  ASSERT_EQ(b, true);
  ASSERT_EQ(store.GetSize(), 2);
  delete pAA;

  ASSERT_EQ(store.Get(1)->GetI(), 1);
  pAA = new AA(2, 2.2f);
  store.Set_d(1, pAA);
  ASSERT_EQ(store.GetSize(), 2);
  ASSERT_EQ(store.Get(1)->GetI(), 2);
}

TEST_F(Test_tpl_store, Get__GetSize) {
  store.Set(0, new AA(0, 0.0f));
  store.Set(1, new AA(1, 1.1f));
  store.Set(2, new AA(2, 2.2f));

  AA* pAA = store.Get(0);
  ASSERT_NE(pAA, nullptr);
  ASSERT_EQ(store.GetSize(), 3);
  pAA = store.Get(1000);
  ASSERT_EQ(pAA, nullptr);
  ASSERT_EQ(store.GetSize(), 3);
}

TEST_F(Test_tpl_store, Remove__GetSize) {
  store.Set(0, new AA(0, 0.0f));
  store.Set(1, new AA(1, 1.1f));
  store.Set(2, new AA(2, 2.2f));

  AA* pAA = store.Remove(1);
  ASSERT_NE(pAA, nullptr);
  ASSERT_EQ(store.GetSize(), 2);
  pAA = store.Remove(1000);
  ASSERT_EQ(pAA, nullptr);
  ASSERT_EQ(store.GetSize(), 2);
}

TEST_F(Test_tpl_store, Clear__GetSize) {
  store.Set(0, new AA(0, 0.0f));
  store.Set(1, new AA(1, 1.1f));
  store.Set(2, new AA(2, 2.2f));

  ASSERT_EQ(store.GetSize(), 3);
  store.Clear();
  ASSERT_EQ(store.GetSize(), 0);
}

TEST_F(Test_tpl_store, Traversal__GetSize) {
  store.Set(0, new AA(0, 0.0f));
  store.Set(1, new AA(1, 1.1f));
  store.Set(2, new AA(2, 2.2f));
  store.Set(3, new AA(3, 3.3f));
  store.Set(4, new AA(4, 4.4f));

  AA* pAA = store.Traversal(true);
  while (pAA) {
    ASSERT_EQ(store.GetSize(), 5);
    pAA = store.Traversal(false);
  }
}

#endif
